package model;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

public class ArcMatrix {
	
	private final Map<Transition, Marking> matrix;
	
	/**
	 * Constructor of {@link ArcMatrix}.
	 * All values of this matrix are set to 0.
	 * @param places are the {@link Place}s of this matrix.
	 * @param transitions are the {@link Transition}s of this matrix.
	 */
	public ArcMatrix(final Vector<Place> places, final Vector<Transition> transitions) {
		this.matrix = new HashMap<Transition, Marking>();
		for (final Transition transition : transitions) {
			final Marking marking = new Marking();
			for (final Place place : places) {
				marking.add(place, 0);
			}
			this.matrix.put(transition, marking);
		}
	}
	
	/**
	 * Sets the value at the position of the provided {@link Place} and {@link Transition}.
	 * @param value is the new value.
	 * @param place is a {@link Place} in this matrix.
	 * @param transition is a {@link Transition} in this matrix.
	 */
	public void setValue(final int value, final Place place, final Transition transition){
		if(this.matrix.containsKey(transition)){
			this.matrix.get(transition).setValue(place, value);
		}
	}
	
	/**
	 * Provides the value at the position specified by the provided {@link Place} and {@link Transition}.
	 * @param place is a {@link Place} in this marix.
	 * @param transition is a {@link Transition}. in this marix.
	 * @return the value at the position in this matrix specified by the provided {@link Place} and {@link Transition}.
	 * @throws Error if the provided {@link Place} or {@link Transition} is not in this matrix.
	 */
	public int getValue(final Place place, final Transition transition){
		return this.matrix.get(transition).getValue(place);
	}

	public Marking multiply(final Transition transition){
		final Vector<Transition> transitions = new Vector<Transition>();
		transitions.add(transition);
		return this.multiply(transitions);
		
	}
	public Marking multiply(final Collection<Transition> transitions) {
		final Marking result = new Marking();
		for (final Map.Entry<Transition, Marking> matrixEntry : this.matrix.entrySet()) {
			if(transitions.contains(matrixEntry.getKey())){
				result.add(matrixEntry.getValue());
			}
		}
		return result;
	}
}